﻿using System;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows.Controls;
using System.Windows.Printing;
using AdventureWorksLT.Core;
using AdventureWorksLT.Views.Customers.ChildWindows;
using AdventureWorksLT.Views.Customers.DesignerData;
using AdventureWorksLT.Views.Customers.Reports;
using AdventureWorksLT.Web.Models;
using AdventureWorksLT.Web.Services;
using System.Collections.ObjectModel;
using System.Windows;
using RelayCommand = AdventureWorksLT.Core.RelayCommand;

namespace AdventureWorksLT.Views.Customers.ViewModels
{
    public class CustomersViewModel : PerformAsyncQueryBase // the AsyncQuery one inherits from ViewModel Base
    {
        public static AdventureWorksLTDomainContext CustomersContext;
        private ObservableCollection<Customer> _customers;
        private AdventureWorksLTDomainContext _context;
        private int _pageIndex = 0;
        //
        public CustomersViewModel()
        {
            if (!IsDesignTime)
            {
                CustomersContext = new AdventureWorksLTDomainContext();
                IsBusy = true;
                WireCommands();
                LoadCustomersAsync();
                LoadComboBoxData();
            }
            else
            {
                DesignTimeCustomer _designTimeCustomer = new DesignTimeCustomer();
                CustomersCollection = new ObservableCollection<Customer>(_designTimeCustomer.ToList());
                CurrentCustomers = CustomersCollection.FirstOrDefault();
            }
        }
        #region "Load Current Customers"
        //readonly int loadedCustomerID = AdventureWorksLT.Views.Customers.ViewModels.CustomersViewModel.DashLoad_PK;
        private void LoadCustomersAsync()
        {
            if (!CustomersContext.IsSubmitting)
            {
                if (DashLoad_PK > 0)
                {
                    PerformAsyncQuery<Customer>(CustomersContext, CustomersContext.GetCustomersForCustomerQuery(DashLoad_PK), CustomersLoadedComplete);
                }
                else
                {
                    PerformAsyncQuery<Customer>(CustomersContext, CustomersContext.GetCustomersQuery(), CustomersLoadedComplete);
                }
            }
        }

        private ObservableCollection<Customer> _customersCollection;
        public ObservableCollection<Customer> CustomersCollection
        {
            get { return _customersCollection; }
            set
            {
                _customersCollection = value;
                RaisePropertyChanged("CustomersCollection");
            }
        }

        private Customer _currentCustomers;
        public Customer CurrentCustomers
        {
            get { return _currentCustomers; }
            set
            {
                _currentCustomers = value;
                RaisePropertyChanged("CurrentCustomers");
            }
        }
        #endregion "Load Current Customers"
        #region Commands


        private void EnableCommands()
        {
            AddNewCommand.IsEnabled = true;
            EditCurrentInNewWindowCommand.IsEnabled = true;
            SaveCommand.IsEnabled = true;
            DeleteCommand.IsEnabled = true;
            PrintCommand.IsEnabled = true;
            SearchCustomersCommand.IsEnabled = true;
            ShowChartDashboardCommand.IsEnabled = true;
            SelectionChangedSdkCommand.IsEnabled = true;
            RowLoadingSdkCommand.IsEnabled = true;
            PreviousPageCommand.IsEnabled = true;
            NextPageCommand.IsEnabled = true;
        }
        private void WireCommands()
        {
            AddNewCommand = new RelayCommand(AddCustomers);
            EditCurrentInNewWindowCommand = new RelayCommand(EditCurrentInNewWindow);
            SaveCommand = new RelayCommand(SaveCustomers);
            DeleteCommand = new RelayCommand(DeleteCustomers);
            PrintCommand = new RelayCommand(PrintCustomers);
            ShowChartDashboardCommand = new RelayCommand<object>(ShowChartDashboard);
            SearchCustomersCommand = new RelayCommand<string>(SearchInCustomers);
            SelectionChangedSdkCommand = new RelayCommand<Customer>(OnExecuteSelectionChangedSdk);
            RowLoadingSdkCommand = new RelayCommand<System.Windows.Controls.DataGridRowEventArgs>(OnExecuteRowLoadingSDK);
            PreviousPageCommand = new RelayCommand(PreviousPage);
            NextPageCommand = new RelayCommand(NextPage);
        }

        private void OnExecuteRowLoadingSDK(System.Windows.Controls.DataGridRowEventArgs e)
        {
            AdventureWorksLT.Web.Models.Customer model = e.Row.DataContext as AdventureWorksLT.Web.Models.Customer;

            var grid = new Grid();
            var tb = new TextBlock
            {
                Text = string.Format(
                     "Name Style : {0} \r\n" + "Title : {1} \r\n" + "First Name : {2} \r\n" + "Middle Name : {3} \r\n" + "Last Name : {4} \r\n" + "Suffix : {5} \r\n" + "Company Name : {6} \r\n" + "Sales Person : {7} \r\n" + "Email Address : {8} \r\n" + "Phone : {9} \r\n" + "Password Hash : {10} \r\n" + "Password Salt : {11} \r\n" + "Rowguid : {12} \r\n" + "Modified Date : {13} \r\n",
                     model.NameStyle, model.Title, model.FirstName, model.MiddleName, model.LastName, model.Suffix, model.CompanyName, model.SalesPerson, model.EmailAddress, model.Phone, model.PasswordHash, model.PasswordSalt, model.rowguid, model.ModifiedDate),
                Margin = new Thickness(3, 3, 3, 3),
                Opacity = 0.8,
                MaxWidth = 250,
                FontSize = 10,
                TextWrapping = TextWrapping.NoWrap
            };
            grid.Children.Add(tb);
            ToolTipService.SetToolTip(e.Row, grid);
        }

        private void OnExecuteSelectionChangedSdk(Customer checkedCustomers)
        {
  
           
            CurrentCustomers = checkedCustomers;
            //DtEnd = System.DateTime.Now.Ticks;
            if (checkedCustomers != null)
            {
            AdventureWorksLT.Views.Customers.ViewModels.SalesOrderHeadersViewModel.DashLoad_PK = checkedCustomers.CustomerID;
            }
            // gives the data, so the next time the Ria is queried, this is the customer id
        }

        private void NextPage()
        {
            _pageIndex++;
            CustomersCollection = new ObservableCollection<Customer>(CustomersContext.Customers.Skip(_pageIndex * 20).Take(20));
            CurrentCustomers = CustomersCollection.FirstOrDefault();
        }

        private void PreviousPage()
        {
            _pageIndex--;
            CustomersCollection = new ObservableCollection<Customer>(CustomersContext.Customers.Skip(_pageIndex * 20).Take(20));
            CurrentCustomers = CustomersCollection.FirstOrDefault();
        }


        public RelayCommand<System.Windows.Controls.DataGridRowEventArgs> RowLoadingSdkCommand
        {
            get;
            private set;
        }

        public RelayCommand<Customer> SelectionChangedSdkCommand
        {
            get;
            private set;
        }

        public RelayCommand PreviousPageCommand
        {
            get;
            private set;
        }

        public RelayCommand NextPageCommand
        {
            get;
            private set;
        }

        public RelayCommand AddNewCommand
        {
            get;
            private set;
        }

        public RelayCommand EditCurrentInNewWindowCommand
        {
            get;
            private set;
        }

        public RelayCommand SaveCommand
        {
            get;
            private set;
        }



        public RelayCommand DeleteCommand
        {
            get;
            private set;
        }

        public RelayCommand PrintCommand
        {
            get;
            private set;
        }

        public RelayCommand<object> ShowChartDashboardCommand
        {
            get;
            private set;
        }

        public RelayCommand<string> SearchCustomersCommand
        {
            get;
            private set;
        }
        #endregion Commands

        private void SearchInCustomers(string searchText)
        {
            MessageBox.Show(searchText);
        }


        public void SaveCustomers()
        {

            CustomersContext.SubmitChanges(OnCallbackSave, null);
        }

        private void OnCallbackSave(SubmitOperation p)
        {
            if (p.HasError)
            {
                p.MarkErrorAsHandled();
                ErrorWindow.CreateNew(p.Error);
            }
            else
            {
                MessageBox.Show("Customers se ha actualizado");
                RaisePropertyChanged("CustomersCollection");
                RaisePropertyChanged("CurrentCustomers");
            }
        }
        #region "Add New & Edit"
        //http://forums.silverlight.net/forums/p/193377/449256.aspx
        private void AddCustomers()
        {
            AdventureWorksLT.Web.Models.Customer customers = new AdventureWorksLT.Web.Models.Customer();
            CustomerAddCW addNewWindow = new CustomerAddCW();
            addNewWindow.DataContext = customers;
            addNewWindow.Closed += (s, ee) =>
            {
                if (addNewWindow.DialogResult == true)
                {

                    CustomersContext.Customers.Add(customers);
                    CustomersContext.SubmitChanges(p =>
                    {
                        if (p.HasError)
                        {
                            p.MarkErrorAsHandled();
                            ErrorWindow.CreateNew(p.Error);
                        }

                        else
                        {
                            MessageBox.Show("New Customers has been added");
                        }
                    }, null);
                }

            };
            addNewWindow.Show();
            addNewWindow.Closed += FrmClosedAdd;
        }

        void FrmClosedAdd(object sender, EventArgs e)
        {
            DashLoad_PK = 0; // to load all Customers
            // The only time that the DashLoad_PK does not need to be made zero, is when what is closing is the Child Grid in a master-Child Invoice type.
            // Because the details Grid needs to keep the filter, is a Details for one particular header invoice

            LoadCustomersAsync();
        }

        public static int CCustomerID;
        private void ObtainCustomerID()
        {

            string a = CurrentCustomers.CustomerID.ToString();
            int dashLoadPk;
            int.TryParse(a, out dashLoadPk);
            DashLoad_PK = dashLoadPk;
            CCustomerID = dashLoadPk;

        }

        private void EditCurrentInNewWindow()
        {
            ObtainCustomerID();
            if (CCustomerID > 0)
            {
                var frm = new ChildWindows.CustomerCW();
                frm.Show();
                frm.Closed += new System.EventHandler(FrmClosed);
            }
        }

        void FrmClosed(object sender, System.EventArgs e)
        {
            DashLoad_PK = 0;
            // The only time that the DashLoad_PK does not need to be made zero, is when what is closing is the Child Grid in a master-Child Invoice type.
            // Because the details Grid needs to keep the filter, is a Details for one particular header invoice
            LoadCustomersAsync();
        }

        #endregion "Add New & Edit"

        private static int _dashload_PK;
        public static int DashLoad_PK
        {
            get { return _dashload_PK; }
            set { _dashload_PK = value; }
        }

        private void ShowChartDashboard(object selectedItem)
        {
            string a = selectedItem.ToString();
            int i = a.IndexOf(":") + 1;
            a = a.Substring(i);
            int dashLoadPk;
            int.TryParse(a, out dashLoadPk);
            DashLoad_PK = dashLoadPk;
            Uri target = new Uri("/Customers/Pages/PatientsTitlePage?CustomerID=" + DashLoad_PK, UriKind.Relative);
            var _theItem = selectedItem;
            CurrentCustomers = (Customer)_theItem;
            //NavigationService.Navigate(target);
            //var service = ((Page)((App)Application.Current).RootVisual).NavigationService;
            //if (service != null) service.Navigate(target);
        }

        private bool _isBusy;
        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                _isBusy = value;
                RaisePropertyChanged("IsBusy");
            }
        }

        public string CurrentTime
        {
            get
            {
                DateTime time = DateTime.Now;
                const string format = "MMM ddd d HH:mm yyyy";
                return (time.ToString(format));
            }
        }

        #region "Security"
        //Security methods
        private void CheckSecurity()
        {
            // Add code for LoggedIn and LoggedOut events
            WebContext.Current.Authentication.LoggedIn += Authentication_Changed;
            WebContext.Current.Authentication.LoggedOut += Authentication_Changed;
        }

        void Authentication_Changed(object sender, System.ServiceModel.DomainServices.Client.ApplicationServices.AuthenticationEventArgs e)
        {
            RaisePropertyChanged("IsAdmin");
        }

        private bool _IsAdmin;
        public bool IsAdmin
        {
            get { return CheckUserIsInRole("Admin"); }
        }

        private bool CheckUserIsInRole(string role)
        {
            return WebContext.Current.User.IsInRole(role);
        }

        //<HyperlinkButton x:Name="AdminLink" Visibility="{Binding IsAdmin,Converter={StaticResource BoolToVisibilityConverter},FallbackValue=Collapsed}" TargetName="ContentFrame" NavigateUri="/AdminView" Content="Admin" Style="{StaticResource LinkStyle}" />
        // CurrentUser is needed for logging
        public string CurrentUser
        {
            get { return WebContext.Current.User.ToString(); }
        }

        #endregion "Security"

        #region "LoadComboBoxData"

        void LoadComboBoxData()
        {
            //dtStart = System.DateTime.Now.Ticks;
        }


        private void CustomersLoadedComplete(object sender, AdventureWorksLT.Core.EntityResultsArgs<Customer> e)
        {
            IsBusy = false;
            if (!e.HasError)
            {
                //CustomersCollection = CustomersContext.Customer;
                CustomersCollection = new ObservableCollection<Customer>(CustomersContext.Customers.OrderBy(c => c.CustomerID).Take(20));
                CurrentCustomers = CustomersCollection.FirstOrDefault();
                EnableCommands();
            }
            else
            {
                // notify user if there is any error
                //AppMessages.RaiseErrorMessage.Send(e.Error);
            }
        }



        #endregion "LoadComboBoxData"
        #region "Delete"
        private bool _toDelete = false;
        private void DeleteCustomers()
        {
            _toDelete = true;
            var customersToDelete = CurrentCustomers;
            if (customersToDelete != null)
            {
                var result = MessageBox.Show("Are you sure you wish to delete the Current Customers?", "Confirm Delete", MessageBoxButton.OKCancel);
                if (result.Equals(MessageBoxResult.OK))
                {
                    CustomersContext.Customers.Remove(customersToDelete);
                    CustomersContext.SubmitChanges(o =>
                    {
                        if (o.HasError)
                        {
                            MessageBox.Show("Esta customers no se puede eliminar ya que existen datos que dependen de esta Customers.....", "Cancelado", MessageBoxButton.OKCancel);
                            o.MarkErrorAsHandled();
                            CustomersContext.RejectChanges();
                        }

                        else
                        {
                            MessageBox.Show("the record has been deleted ... ");
                            DashLoad_PK = 0; // to load all Customers

                            // The only time that the DashLoad_PK does not need to be made zero, is when what is closing is the Child Grid in a master-Child Invoice type.
                            // Because the details Grid needs to keep the filter, is a Details for one particular header invoice
                            LoadCustomersAsync();

                            //RaisePropertyChanged("CustomersCollection");
                            //CurrentCustomers = CustomersCollection.FirstOrDefault();
                        }
                    }, null);
                }
            }
            _toDelete = false;
        }
        #endregion "Delete"
        #region "Print"

        private void PrintCustomers()
        {
            if (CurrentCustomers != null)
            {
                PrintDocument document = new PrintDocument();
                document.PrintPage += new System.EventHandler<PrintPageEventArgs>(document_PrintPage); // fires when every single page is going to print 
                document.EndPrint += new System.EventHandler<EndPrintEventArgs>(document_EndPrint); // when printing is completed
                string PrintQueue = "Customer_" + CurrentCustomers.ToString(); // to show in the print queue
                document.Print(PrintQueue); //fires when printing has begun
            }
        }

        static void document_EndPrint(object sender, EndPrintEventArgs e)
        {
            if (e.Error != null)
            {
                ErrorWindow error = new ErrorWindow(e.Error.Message, e.Error.StackTrace);
            }

            else
                MessageBox.Show("Print Complete");
        }

        void document_PrintPage(object sender, PrintPageEventArgs e)
        {
            PrintDocument document = sender as PrintDocument;
            AdventureWorksLT.Web.Models.Customer appt = CurrentCustomers as AdventureWorksLT.Web.Models.Customer;
            if (appt != null)
            {
                //e.HasMorePages = appt.ChildEntity != null && document.PrintedPageCount < appt.ChildEntity.Count;
                //if (document.PrintedPageCount > 0)
                //{
                // e.PageVisual = new ChildEntityFReport() { DataContext = appt.ChildEntity.ElementAt(document.PrintedPageCount - 1) };
                //}
                //else
                e.PageVisual = new CustomerFReport() { DataContext = appt };
            }
        }
        #endregion "Print"

        #region DoubleClick

      
      

        #endregion DoubleClick
    }
}